//#include <iostream>
#include "serialize.hpp"
using namespace std;

serialize::serialize(){

//	data_p 		= (char *) malloc( INIT_CAPACITY );
//	capacity	= INIT_CAPACITY;
	data_p		= NULL;
	capacity	= 0;
	write_pos	= 0;
	read_pos	= 0;
}

serialize::~serialize(){
	clean();
}

void 
serialize::clean(){
	if( data_p ){
		delete[] data_p;
		data_p = NULL;
	}
	capacity	= 0;
	write_pos	= 0;
	read_pos	= 0;
}	

int 
serialize::write( char * content_p , unsigned int size ){

	if( 0 == size || NULL == content_p ){
		return -1;
	}

	// If there isn't enough memory to store the new data ,
	// increase the size of data buffer automatically .
	if( (write_pos + size) > capacity ){ 

		int inc_size = ( size/BLK_SIZE + 1)* BLK_SIZE;
		int new_size = inc_size + capacity;

		char * newdata_p = (char *)realloc( data_p , new_size );

		if( !newdata_p ){
			return -2;
		}

		memset( (newdata_p + write_pos ) , 0 ,inc_size );

		data_p = newdata_p;

		capacity = new_size;

	}
		
	memcpy( W_PTR , content_p , size );

	INC_W( size );
		
	return size;
}

int 
serialize::read( char * content_p , unsigned int size ){

	unsigned int remain , copysize ;

	if( 0 == size || NULL == content_p ){
		return -1;
	}
		
	remain = write_pos - read_pos;

	copysize = remain < size ? remain : size  ;
		
	memcpy( content_p , R_PTR , copysize );

	INC_R( copysize );

	return copysize;
}

serialize & 
serialize::operator <<( char * data_c_p){
	write( data_c_p , strlen(data_c_p) );
	return *this;
}

serialize &
serialize::operator <<(char data_c ){
	write( (char * )&data_c , sizeof(char) );
	return *this;
}

serialize &
serialize::operator <<(unsigned char data_c ){
	 write( (char * )&data_c , sizeof(unsigned char) );
	return *this;
}

serialize &
serialize::operator <<(short int data_si ){
	 write( (char *)&data_si , sizeof(short int) );
	return *this;
}

serialize &
serialize::operator <<( unsigned short int data_usi ){
	 write( (char *)&data_usi , sizeof( unsigned short int ) );
	return *this;
}

serialize &
serialize::operator <<(int data_i ){
	 write( (char * )&data_i , sizeof(int) );
	return *this;
}

serialize &
serialize::operator <<(unsigned int data_i){
	 write( (char *)&data_i , sizeof(unsigned int) );
	return *this;
}

serialize &
serialize::operator <<( long data_l ){
	 write( (char *)&data_l , sizeof( long ) );
	return *this;
}

serialize &
serialize::operator <<( unsigned long data_ul ){
	 write( (char *)&data_ul , sizeof( unsigned long ) );
	return *this;
}

serialize &
serialize::operator <<( string data_str ){
	 write( (char *)data_str.c_str() , data_str.size() );
	return *this;
}

serialize &
serialize::operator >>(char & data_c ){
	 read( (char * )&data_c , sizeof(char) );
	return *this;
}

serialize &
serialize::operator >>(unsigned char & data_c ){
	 read( (char * )&data_c , sizeof(unsigned char) );
	return *this;
}

serialize &
serialize::operator >>(short int & data_si ){
	 read( (char *)&data_si , sizeof(short int) );
	return *this;
}

serialize &
serialize::operator >>( unsigned short int & data_usi ){
	 read( (char *)&data_usi , sizeof( unsigned short int ) );
	return *this;
}

serialize &
serialize::operator >>(int & data_i ){
	 read( (char * )&data_i , sizeof(int) );
	return *this;
}

serialize &
serialize::operator >>(unsigned int & data_i){
	 read( (char *)&data_i , sizeof(unsigned int) );
	return *this;
}

serialize &
serialize::operator >>( long & data_l ){
	 read( (char *)&data_l , sizeof( long ) );
	return *this;
}

serialize &
serialize::operator >>( unsigned long & data_ul ){
	 read( (char *)&data_ul , sizeof( unsigned long ) );
	return *this;
}

